#include "Order.h"
#include <iostream>
#include <vector>
#include <ostream>
#include "State.h"
#include "Bug.h"
#include "Map.hh"
#include "Strategy.hh"

/// Comparision criterion
bool same_source(const IndividualOption & a, const IndividualOption & b)
{
  return (a.from==b.from);
}

/// sort criterion
bool by_src_and_decreasing_weight(const IndividualOption & a, const IndividualOption & b)
{
  return (a.from<b.from) or ((a.from == b.from) and (a.w>b.w));
}

/// comparision criterion
bool same_dest(const IndividualOption & a, const IndividualOption & b)
{
  return a.to==b.to;
}

/// sort criterion
bool by_dest_and_decreasing_weight(const IndividualOption & a, const IndividualOption & b)
{
  return (a.to<b.to) or ((a.to == b.to) and (a.w>b.w));
}


/// normalization action
void normalize_action(std::list<IndividualOption>::iterator first, std::list<IndividualOption>::iterator last)
{
  double Z = 0;
  for(std::list<IndividualOption>::iterator i = first; i!=last; ++i)
    Z+= fabs(i->w);
  if (Z)
  {
      for(std::list<IndividualOption>::iterator i = first; i!=last; ++i)
        i->w /= Z;
  }
}

void 
Order::proposeMove(State & s, const uLocation &from, const uLocation &to, int direction, double w)
{
   // TU experiment : try to combine battle resolution with move scheduling
  if(may_die(s,to)) w = w -100.0;
  push_back(IndividualOption(from,to,direction,w));
}

void 
Order::execute(State & s, bool simulation)
{
    TRACK();

    bug << "* before selection" << std::endl;
    bug << *this << std::endl;
    //dump(bug,s) << std::endl;
    

    // removes incompatible options
    solve_conflicts();

    bug << "* after removing conflicts" << std::endl;
    bug << *this << std::endl;

    select_best();

    bug << "* after selecting best" << std::endl;
    bug << *this << std::endl;

  //if(conf>0) bug << "conflicts: " << conf << std::endl;

  // the order is now a 'valid' order in my sense
  // but NOT in the organizers sense:
  // i.e. no pair of ants goes to the same location
  // BUT: they may collide with orgiginal positions!!!

  // remove 'no move' orders
  iterator it=begin();
  while( it != end() )
    {
      if (( it->direction) == -1)
	{ // no move
	  it=erase(it);
	}
      else
	{
	  it++;
	}
    }

  s.last_aim.clear();

  // iterate orders until possibles
  unsigned changes=1;
  while(changes>0)
    {
      changes=0;
      bug << "solving conflicts and executing valid move" << std::endl;
      for(it=begin(); it!=end();++it)
	{
          if(s.location(it->to).ant == -1)
	    { // valid move
	     
	      changes++;
	      if(simulation)
		s.simulateMove(it->from, it->to);
	      else
		s.makeMove(it->from, it->direction);
	    }
	}
    }

}


/* dump for debug */
std::ostream& operator<<(std::ostream &os, const Order &order)
{
    for (Order::const_iterator it=order.begin(); it != order.end(); ++it)
    {
        os << it->w << "." << "("
          << Map::GlobalMap->get_row(it->from) << "," << Map::GlobalMap->get_col(it->from)
           << ") -> ("
           << Map::GlobalMap->get_row(it->to) << "," << Map::GlobalMap->get_col(it->to)
           << ")";
        if (it->direction>=0)
            os << " [" << CDIRECTIONS[it->direction] << "]";
        else
            os << " [-]";
        os << std::endl;
    }
    return os;
}


	
